<?PHP
defined('_XR_EXEC') or die();
 /**
 * 框架错误处理
 * @param string $errno 		错误类别序号，请参照函数内$errortype定义的错误类别数组
 * @param string $errmsg 		抛出的错误信息
 * @param string $filename 	所在文件
 * @param string $linenum 	所在文件行数
 * @param string $vars 			当前的环境变量数组
 *
 * by zhoupeng 2012-3-15  
 * @zhoupeng10@gmail.com
 *
 */
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars) 
{
	$o_errorHandler = Errors::singleton();
	$o_errorHandler->errorHappen($errno, $errmsg, $filename, $linenum);
}
//set_error_handler("userErrorHandler",E_ALL);


/* 测试方法

1 trigger_error("this is a error by myself",User Notice);
2 $zhou = 9/0;

*/


/**
* 错误处理类
* by zhoupeng 2012-3-15
*
*
*
*/
class Errors{
	var $b_recordError 	= true;//是否记录日志
	var $b_displayError = true;//是否显示真实错误数据
	
	# 实例化自己
	public static function singleton()
	{
		static $instances;
		if (!isset ($instances))
		{
			$instances = new Errors();
		}
		return $instances;
	}
	
	public function __construct(){
		$this->init();
	}
	
	/**
	* 获取一些配置文件，错误日志记录，错误日志展示等
	*
	*
	*/
	public function init(){
		$this->b_recordError = factory::getcfg('log_errors',true);
		$this->b_displayError = factory::getcfg('display_errors',true);
	}
	/**
	* 主动触发错误显示
	*
	*
	*/
	public static function go($errmsg, $filename='', $linenum=0){
		$th = Errors::singleton();
		$th->errorHappen(E_ERROR,$errmsg, $filename , $linenum);
	}
	/**
	* 错误发生的执行函数
	*
	*
	*/
	public function errorHappen($errno, $errmsg, $filename='', $linenum=0 ){
    //时间
    $dt = date("Y-m-d H:i:s (T)");
    //所有错误类别
    $errortype = array (
			E_ERROR           => "Error",
			E_WARNING         => "Warning",
			E_PARSE           => "Parsing Error",
			E_NOTICE          => "Notice",
			E_CORE_ERROR      => "Core Error",
			E_CORE_WARNING    => "Core Warning",
			E_COMPILE_ERROR   => "Compile Error",
			E_COMPILE_WARNING => "Compile Warning",
			E_USER_ERROR      => "User Error",
			E_USER_WARNING    => "User Warning",
			E_USER_NOTICE     => "User Notice",
			E_STRICT          => "Runtime Notice"
		);
    //以下几种状态是可以记录环境变量的
    $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
    //开始组装错误日志
    $err = "<errorlog>\n";
    $err .= "\t<date>" . $dt . "</date>\n";
    $err .= "\t<errornum>" . $errno . "</errornum>\n";
    $err .= "\t<types>" . $errortype[$errno] . "</types>\n";
    $err .= "\t<msg>" . $errmsg . "</msg>\n";
    $err .= "\t<script>" . $filename . "</script>\n";
    $err .= "\t<line>" . $linenum . "</line>\n";
    $err .= "</errorlog>\n\n";
		//记录日志
		if($this->b_recordError === true){
			logs::note($err,'ErrorLog');
		}
		//展示详细错误或者输出
		if($this->b_displayError === true){
			echo $this->errorHtml($errno, $errmsg, $filename, $linenum );
		}else{
			echo $this->errorHtmlSimple($errno, $errmsg, $filename, $linenum );
		}
		exit();
	}
	
	
	/**
	* 显示详细错误信息
	* 
	* 
	*/
	public function errorHtml($errno, $errmsg, $filename, $linenum){
 		$s_html = '';
		$s_html .= $this->htmlBodyHead();
		$end_time = array_sum(explode(' ', microtime()));
		$var=sprintf('%.6f',$end_time-XR_START_TIME);
		$s_html .= '
			<div class="box" >
				<div class="title" >请求错误</div>
				<div class="body" >';
		if($filename!=''){
		$s_html .= '		
					<div class="line">'.$filename.'<span class="red">['.$linenum.']:</span></div>
				';
		}
		$s_html .= '
					<div class="line_bg">'.strip_tags($errmsg).'</div>
				</div>
			</div>		
			<div class="box" >
				<div class="title" >Error Trace</div>
				<div class="body" > 
					<div class="line">Host</div>
					<div class="line_bg">'.url::base().'</div>
					<div class="line">Uri</div>
					<div class="line_bg">'.url::selfUri().'</div> 
					<div class="line">GET</div>
					<div class="line_bg"><pre>'.var_export($_GET,true).'</pre></div> 
					<div class="line">POST</div>
					<div class="line_bg"><pre>'.var_export($_POST,true).'</pre></div> 
					<div class="line">Memory</div>
					<div class="line_bg">'.number_format((memory_get_usage()/1024/1024),4).' M</div> 
					<div class="line">Parse Time</div>
					<div class="line_bg">'.$var.'</div> 
				</div>
			</div>		
		';
		$s_html .= $this->htmlBodyFoot();
		return $s_html;
	}
	/**
	* 不显示详细错误信息，只出错误提示
	*
	*
	*/
	public function errorHtmlSimple($errno, $errmsg, $filename, $linenum){
		$s_html = '';
		$s_html .= $this->htmlBodyHead();
		
		$s_html .= '
			<div class="box" >
				<div class="title" >请求错误</div>
				<div class="body" >
					您可以返回 <a href="'.url::base().'">首页</a> 或 <a href="'.url::selfUri().'">再试一次</a>
				</div>
			</div>		
		';
		
		$s_html .= $this->htmlBodyFoot();
		return $s_html;
	}
	
	
	
	/**
	* 错误显示的Html head
	*
	*
	*/
	private function htmlBodyHead(){
		return '
			<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
			<html xmlns="http://www.w3.org/1999/xhtml">
			<head>
			<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
			<title>请求错误</title>
			</head>
			<style type="text/css">
			body{
			background-color:#f0f0f0;font-size:14px;
			margin:0px
			}
			a{
			color:#16387C;
			text-decoration:none;
			}
			a:hover{
			text-decoration:underline;
			}
			.box{
			margin:10px auto;border:1px solid #BBC5CD;background-color:#FFFFFF;width:600px;
			}
			.box .title{
			padding:10px;background-color:#F5F7F8;color:#16387C;border-bottom:1px solid #BBC5CD;font-weight:bold;text-align:center;font-size:14px;
			}
			.box .body{
			padding:10px;color:#2D2D2D
			}
			.box .body .line{
			margin:10px auto;
			}
			.box .body .line_bg{
			margin:10px auto;
			padding:5px;
			color:#333333;
			border-right:1px solid #CCCCCC;
			border-bottom:1px solid #CCCCCC;
			background-color:#EAEEE5;
			}
			span.red{
			color:#CC0000;
			font-style:italic;
			font-weight:bold;
			}
			</style>
			<body>		
		';
	}
	/**
	* 错误显示的Html foot
	*
	*
	*/
	private function htmlBodyFoot(){
		return '
			</body>
			</html>
		';
	}

	 
	
	
}
?>